set V;
set T;
set L;

param C{i in V, j in V};
param E{i in V, j in V};

param D := 5;

# Defino las Variables de decision Xij e Yuvl(i,j) */
var x{i in V, j in V}, binary;
var y{u in T, v in T, l in L, i in V, j in V}, binary;

 
############# /* Funcion objetivo */ ###################
minimize obj: sum{i in V, j in V} C[i,j] * x[i,j];
########################################################


#1 /* de cada nodo terminal salen al menos una arista para cada camino l*/
s.t. salenTerminal{l in L, u in T, v in T: v!=u}: sum{i in V: C[u,i]>0} y[u,v,l,u,i] >= 1;

#2 de cada nodo terminal, y por cada camino, entran al menos una arista */
s.t. entranTerminal{l in L, u in T, v in T: v<>u}: sum{i in V: C[i,v]>0} y[u,v,l,i,v] >= 1;

#balance
#s.t. res3{u in T, v in T, l in L, p in V}: sum{i in V} y[u,v,l,i,p] <= 1; # innecesaria, ya que estamos minimizando
s.t. bal3{u in T, v in T, l in L, p in V : p<>v && p<>u}: sum{j in V} y[u,v,l,p,j] - sum{i in V} y[u,v,l,i,p] >= 0;

#saltos
s.t. saltos{l in L, u in T, v in T: v<>u }: sum{i in V, j in V: C[i,j]>0} y[u,v,l,i,j] <= D;

# hay una arista en el camino que une u y v 
#s.t. res5{u in T, v in T, p in V, q in V : u!=v}:  y[u,v,l,p,j] + y[u,v,l,p,j] + y[u,v,l,p,j] + y[u,v,l,p,j]   =  x[];
# 
s.t. res5{u in T, v in T, p in V, q in V : u!=v}: sum{l in L} (y[u,v,l,q,p]+ y[u,v,l,p,q])  =  x[q,p];

solve;
printf "Solución\n";
printf {i in V, j in V: j>i && x[i,j]>0}: "Arista (%s,%s) es %d\n", i, j, x[i,j];

# printf "\n Graph-viz \n";
printf "graph g{\n" > "solucion.gv";
printf {i in V}: "%s [shape = %s];\n", i, if(i in T) then 'doublecircle' else 'circle' >> "solucion.gv";
printf {i in V, j in V: j>i && x[i,j]>0}: "\t %s--%s [ label=%s];\n", i, j, C[i,j] >> "solucion.gv";
printf "}\n" >> "solucion.gv";

printf "graph g2{\n" > "inicial.gv";
printf {i in V}: "%s [shape = %s];\n", i, if(i in T) then 'doublecircle' else 'circle' >> "inicial.gv";
printf {i in V, j in V: j>i && C[i,j]>0}: "\t %s--%s [ label=%s];\n", i, j, C[i,j] >> "inicial.gv";
printf "}\n" >> "inicial.gv";


for{u in T, v in T : u!=v}{
  printf "graph g{\n" > "camino" & u & v & ".gv";
  printf {i in V}: "%s [shape = %s];\n", i, if(i in T) then 'doublecircle' else 'circle' >> "camino"& u & v &".gv";
  printf {i in V, j in V: j>i && C[i,j]>0}: "\t %s--%s [ label=%s];\n", i, j, C[i,j] >> "camino"& u & v &".gv";
  printf {i in V, j in V:  y[u,v,1,i,j]>0}: "\t %s--%s [ color=""#00ff00""];\n", i, j >> "camino" & u & v & ".gv";  
  printf {i in V, j in V:  y[u,v,2,i,j]>0}: "\t %s--%s [ color=""#0000ff""];\n", i, j >> "camino" & u & v & ".gv";
  printf "}\n" >> "camino" & u & v & ".gv";
}

end;
